import { useEffect, useState, useCallback, useRef, FC, useMemo } from "react";
import i18n from "i18n-js";
import { observer } from 'mobx-react';
import Taro from "@tarojs/taro";
import { DynamicColors, GStyleSheet } from "@/utils/DarkMode";
import { View, Text, Image } from "@tarojs/components";
import PageContainer from "@/components/PageContainer";
import FlexScrollView from "@/components/FlexScrollView";
import { GButton } from "@/components/GButton";
import { IProduct } from '@/config/product';
import homesModel from "@/models/homes";
import { deviceDefaultName } from "@/models/deviceList";
import languageModal from "@/models/language";
import { useDeviceListStore } from '@/hooks';
import { isSameDevice } from '@/utils'
import SDK from "@/utils/SDK";
import BleCheckTip from "@/container/BleCheckTip";
import configWifiModel from '../models/configWifi';
import Searching from '../components/Searching';
import RadarTitle from '../components/RadarTitle';
import ConfigDeviceItem, { ConfigStateEnum, IStateClick } from '../loading/BTWifiConifg/ConfigDeviceItem';
import bleAddIcon from "../assets/add_device_icon_ble.png";
import { backToHome } from '../models/configTool';
import SearchingView from '../components/SearchingView';


const btWifiIcon = 'https://xbgroup-1251025085.cos.ap-guangzhou.myqcloud.com/cybertron/users/375869/media/btWifiIcon_1653299554549.png';

export interface IStateDevice extends IDevice {
  state: ConfigStateEnum;
}

const dstyles = GStyleSheet.create({
  container: {
    width: "100%",
    flex: 1,
    flexDirection: 'column',
    height: '100%',
    overflow: 'hidden'
  },
  header: {
    width: "100%",
    paddingLeft: 40,
    paddingTop: 20,
  },
  headerText: {
    color: DynamicColors.titleTextColor,
    fontSize: 18,
    fontWeight: 500,
  },
  findView: {
    width: "100%",
    justifyContent: "flex-start",
    marginBottom: 20
  },
  findIcon: {
    width: 25,
    height: 25,
    marginRight: 10,
  },
  list: {
    width: "100%",
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'flex-start',
    overflow: 'hidden'
  }
});

const maxProgress = 100; // 最大进度是100
const congfigTime = 100; // 配网时间100s

interface IProps {
  productConfig?: IProduct;
  shortShow?: boolean;
}

const BLeAddConifg: FC<IProps> = ({ shortShow = true }) => {

  const styles = dstyles.useDynamicStyle();
  const [progress, setProgress] = useState(0);
  const progressRef = useRef(progress);
  const showRef = useRef(true);

  useEffect(() => {
    showRef.current = true;
    return () => {
      showRef.current = false;
    }
  }, [])

  const { sdkBleDevices, data } = useDeviceListStore();
  console.log('sdkBleDevices', sdkBleDevices);
  const [bindRecordList, setBindRecordList] = useState<IStateDevice[]>([]);
  const bindingRef = useRef(false);
  const bindQueueRef = useRef<IStateDevice[]>([]);

  const bleDevicesRef = useRef<IStateDevice[]>([]);

  const canConifgBleDevices = useMemo(() => {
    console.log('data', data);
    const filterPKDevices = sdkBleDevices.filter((i) => data.findIndex((d) => isSameDevice(d, i)) < 0);
    return filterPKDevices;
  }, [sdkBleDevices, data])

  console.log('canConifgBleDevices', canConifgBleDevices);

  const list = useMemo(() => {
    // return data;
    let arr = bleDevicesRef.current;
    if (arr && arr.length > 0) {
      // 把ready状态的与canConifgBleDevices比较，不存在的就删掉
      arr = arr.filter((i) => {
        if (i.state == ConfigStateEnum.ready) {
          return canConifgBleDevices.findIndex((bleDevice) => isSameDevice(bleDevice, i)) > -1;
        }
        return true;
      })
    }
    bindRecordList.forEach(bindDevice => {
      const index = arr.findIndex(i => isSameDevice(bindDevice, i));
      if (index > -1) {
        arr.splice(index, 1, { ...bindDevice });
      }
    })
    canConifgBleDevices.forEach((d) => {
      const index = arr.findIndex(i => isSameDevice(d, i));
      if (index < 0) {
        arr.push({ ...d, state: ConfigStateEnum.ready });
      }
    })
    bleDevicesRef.current = arr;
    return arr;
  }, [canConifgBleDevices, bindRecordList]);

  console.log('useBleConfigManager', list);

  const updateDeviceState = useCallback((device: IStateDevice) => {
    const index = bindRecordList.findIndex(bindDevice => isSameDevice(bindDevice, device));
    if (index > -1) {
      bindRecordList.splice(index, 1, device);
    } else {
      bindRecordList.push(device);
    }
    setBindRecordList([...bindRecordList]);
  }, [bindRecordList]);

  const configDeviceFunRef = useRef<(deivce: IStateDevice) => void>();

  const checkBindQueue = useCallback(() => {
    if (showRef.current) {
      if (bindQueueRef.current && bindQueueRef.current.length > 0) {
        const device = bindQueueRef.current.splice(0, 1);
        if (configDeviceFunRef.current) {
          configDeviceFunRef.current(device[0])
        }
      }
    } else {

    }
  }, []);

  const configDevice = useCallback(async (device: IStateDevice) => {
    console.log(bindingRef.current);
    if (bindingRef.current) {
      // 如果绑定中，就把要绑定的设备放进绑定队列
      const index = bindQueueRef.current.findIndex(i => isSameDevice(i, device));
      if (index < 0) {
        bindQueueRef.current.push(device);
        updateDeviceState({ ...device, state: ConfigStateEnum.preLoading });
      }
      return {};
    }
    bindingRef.current = true;

    updateDeviceState({ ...device, state: ConfigStateEnum.loading });
    console.log('deviceSafetyRegister ', device)
    const configRes = await SDK.deviceSafetyRegister(device);
    console.log('deviceSafetyRegister res', configRes)
    if (configRes.success) {
      const deviceName = deviceDefaultName(device, languageModal);
      const aepRes = await homesModel.addDevice({ device: { ...device, name: deviceName } });
      console.log('aep绑定结果', aepRes);
      if (aepRes.success) {
        delete aepRes.data.mac;
        const aepDevice = { ...device, ...aepRes.data };
        bindingRef.current = false;
        // deviceListModal.getDeviceList();
        updateDeviceState({ ...aepDevice, state: ConfigStateEnum.success });
        setTimeout(() => {
          checkBindQueue();
        }, 300);
        return;
      }
    }

    bindingRef.current = false;
    updateDeviceState({ ...device, state: ConfigStateEnum.fail });
    checkBindQueue();
  }, [updateDeviceState, checkBindQueue]);

  useEffect(() => {
    configDeviceFunRef.current = configDevice;
  }, [configDevice])

  useEffect(() => {
    progressRef.current = progress;
  }, [progress])

  useEffect(() => {
    SDK.startAutoScan();
  }, [])

  const goToFail = useCallback((noShowRetry = false) => {
    Taro.navigateTo({ url: `/pages/configDevice/bleAdd/failTip?noRetry=${noShowRetry ? 1 : 0}` });
  }, [])

  const itemGoToFail = useCallback(() => {
    goToFail(true);
  }, [goToFail])

  const timerRef = useRef<any>(null);

  const endTimer = useCallback(() => {
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
  }, []);

  const timerAdd = useCallback(() => {
    if (progressRef.current < maxProgress) {
      setProgress(progressRef.current + 1);
    } else {
      endTimer();
      goToFail();
    }
  }, [endTimer, goToFail]);

  const startTimer = useCallback(() => {
    endTimer();
    timerRef.current = setInterval(timerAdd, (congfigTime / maxProgress) * 1000);
  }, [endTimer, timerAdd])

  useEffect(() => {
    if (!shortShow) {
      startTimer()
    }
  }, []);

  useEffect(() => {
    if (list.length > 0) {
      endTimer();
    }
  }, [list, endTimer])

  const deviceItemClick = useCallback(({ device, state }: IStateClick) => {
    if (state == ConfigStateEnum.ready) {
      configDevice({ ...device, state });
    } else if (state == ConfigStateEnum.fail) {
      configDevice({ ...device, state });
    }
  }, [configDevice]);

  const haveDevices = useMemo(() => {
    return list.length > 0;
  }, [list.length])

  const show = useMemo(() => {
    if (shortShow) {
      return true;
    }
    return haveDevices;
  }, [shortShow, haveDevices])

  const onConfirm = useCallback(() => {
    const successDevices = bindRecordList.filter(i => i.state == ConfigStateEnum.success);
    if (successDevices && successDevices.length > 0) {
      successDevices.forEach(i => configWifiModel.addDevice(i));
      backToHome()
    } else {
      goToFail()
    }
  }, [bindRecordList, goToFail])

  const cannotNext = useMemo(() => {
    const index = bindRecordList.findIndex(i => i.state == ConfigStateEnum.loading || i.state == ConfigStateEnum.preLoading);
    return index > -1;
  }, [bindRecordList]);

  // const listStyle = useMemo(() => {
  //   const height = Math.min(100 + list.length * 60, 320);
  //   return (shortShow && haveDevices) ? { maxHeight: 320, height } : { height: 'auto', maxHeight: 'auto' };
  // }, [shortShow, haveDevices, list]);

  const addView = useMemo(() => {
    return (
      <Image src={bleAddIcon} style={{ width: 30, height: 30 }} />
    )
  }, [])

  return (
    <PageContainer title={i18n.t('BLUETOOTH_ADD')}>
      <View style={{ ...styles.container }} className='centerFlex'>
        <View style={{ flex: 1, display: 'flex', flexDirection: 'column', width: "100%", }}>
          <BleCheckTip onChangeBleEnable={(info) => {
            console.log('onChangeBleEnable', info)
          }}>
            {show ?
              <View className='centerFlex' style={styles.list}>
                <View style={styles.header}>
                  <RadarTitle />
                  {haveDevices && <Text style={styles.headerText}>{i18n.t('FOND_DEVICE', { num: list.length })}</Text>}
                </View>
                {haveDevices && <FlexScrollView id='BleAddDevceList' scrollStyle={{ paddingLeft: 20, paddingRight: 20 }}>
                  {list.map((device) => {
                    return <ConfigDeviceItem
                      key={device.mac + device.productKey}
                      device={device}
                      state={device.state}
                      onStateClick={deviceItemClick}
                      goToFailFun={itemGoToFail}
                      addView={addView}
                    />
                  })}
                  {!haveDevices && <SearchingView />}
                </FlexScrollView>}
              </View> :
              <View className='centerFlex' style={{ flex: 1 }}>
                <Searching progress={progress} icon={btWifiIcon} />
              </View>}
          </BleCheckTip>
        </View>
        {(show) && <GButton style={{ marginBottom: 20 }} text={i18n.t('COMPLETED')} onPress={onConfirm} disabled={cannotNext} />}
      </View>
    </PageContainer>
  );
};

export default observer(BLeAddConifg);
